syntax = "proto3";

package kuma.mesh.v1alpha1;

option go_package = "github.com/kumahq/kuma/api/mesh/v1alpha1";

import "api/mesh/options.proto";
import "api/mesh/v1alpha1/metrics.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";
import "kuma-doc/config.proto";

option (doc.config) = {
  type : Other,
  name : "Mesh",
  file_name : "mesh"
};

// Mesh defines configuration of a single mesh.
message Mesh {

  option (kuma.mesh.resource).name = "MeshResource";
  option (kuma.mesh.resource).type = "Mesh";
  option (kuma.mesh.resource).global = true;
  option (kuma.mesh.resource).package = "mesh";
  option (kuma.mesh.resource).kds.send_to_zone = true;
  option (kuma.mesh.resource).ws.name = "mesh";
  option (kuma.mesh.resource).ws.plural = "meshes";

  // mTLS settings of a Mesh.
  message Mtls {

    // Name of the enabled backend
    string enabledBackend = 1 [ (doc.required) = true ];

    // List of available Certificate Authority backends
    repeated CertificateAuthorityBackend backends = 2 [ (doc.required) = true ];

    // If enabled, skips CA validation.
    bool skipValidation = 3;
  }

  // mTLS settings.
  // +optional
  Mtls mtls = 1;

  // Tracing settings.
  // +optional
  Tracing tracing = 2;

  // Logging settings.
  // +optional
  Logging logging = 3;

  // Configuration for metrics collected and exposed by dataplanes.
  //
  // Settings defined here become defaults for every dataplane in a given Mesh.
  // Additionally, it is also possible to further customize this configuration
  // for each dataplane individually using Dataplane resource.
  // +optional
  Metrics metrics = 4;

  // Networking settings of the mesh
  Networking networking = 5;

  // Routing settings of the mesh
  Routing routing = 6;

  // Constraints to apply to the mesh and its entities
  message Constraints {

    // DataplaneProxyMembership defines a set of requirements for data plane
    // proxies to be a member of the mesh.
    DataplaneProxyConstraints dataplaneProxy = 1 [ (doc.required) = true ];
  }

  // Constraints that applies to the mesh and its entities
  Constraints constraints = 7;

  // List of policies to skip creating by default when the mesh is created.
  // e.g. TrafficPermission, MeshRetry, etc. An '*' can be used to skip all
  // policies.
  repeated string skipCreatingInitialPolicies = 8;

  message DataplaneProxyConstraints {

    // Rules defines a set of rules for data plane proxies to be member of the
    // mesh.
    message Rules {
      // Tags defines set of required tags. You can specify '*' in value to
      // require non empty value of tag
      map<string, string> tags = 1 [ (doc.required) = true ];
    }

    // Requirements defines a set of requirements that data plane proxies must
    // fulfill in order to join the mesh. A data plane proxy must fulfill at
    // least one requirement in order to join the mesh. Empty list of allowed
    // requirements means that any proxy that is not explicitly denied can join.
    repeated Rules requirements = 1;
    // Restrictions defines a set of restrictions that data plane proxies cannot
    // fulfill in order to join the mesh. A data plane proxy cannot fulfill any
    // requirement in order to join the mesh.
    // Restrictions takes precedence over requirements.
    repeated Rules restrictions = 2;
  };
}

// CertificateAuthorityBackend defines Certificate Authority backend
message CertificateAuthorityBackend {

  // Name of the backend
  string name = 1 [ (doc.required) = true ];

  // Type of the backend. Has to be one of the loaded plugins (Kuma ships with
  // builtin and provided)
  string type = 2 [ (doc.required) = true ];

  // DpCert defines settings for certificates generated for Dataplanes
  message DpCert {
    // Rotation defines rotation settings for Dataplane certificate
    message Rotation {
      // Time after which generated certificate for Dataplane will expire
      string expiration = 1;
    }
    // Rotation settings
    Rotation rotation = 1;

    // Timeout on request to CA for DP certificate generation and retrieval
    google.protobuf.Duration requestTimeout = 2;
  }

  // Dataplane certificate settings
  DpCert dpCert = 3;

  // Configuration of the backend
  google.protobuf.Struct conf = 4;

  enum Mode {
    // A STRICT mode implies that the server validates the connection and
    // accepts only encrypted TLS traffic
    STRICT = 0;
    // A PERMISSIVE mode implies that the outbounds encrypt traffic the same way
    // it happens in strict mode, but inbounds accept both TLS and plaintext
    // traffic. This allows applications residing in the mesh to accept requests
    // from outside of the mesh.
    PERMISSIVE = 1;
  }

  // Mode defines the behaviour of inbound listeners with regard to traffic
  // encryption
  Mode mode = 5;

  // RootChain defines settings related to CA root certificate chain.
  message RootChain {
    // Timeout on request for to CA for root certificate chain.
    // If not specified, defaults to 10s.
    google.protobuf.Duration requestTimeout = 1;
  }

  RootChain rootChain = 6;
}

// Networking defines the networking configuration of the mesh
message Networking {

  // Outbound describes the common mesh outbound settings
  message Outbound {
    // Control the passthrough cluster
    google.protobuf.BoolValue passthrough = 1;
  }

  // Outbound settings
  Outbound outbound = 1;
}

// Tracing defines tracing configuration of the mesh.
message Tracing {

  // Name of the default backend
  string defaultBackend = 1 [ (doc.required) = true ];

  // List of available tracing backends
  repeated TracingBackend backends = 2 [ (doc.required) = true ];
}

// TracingBackend defines tracing backend available to mesh. Backends can be
// used in TrafficTrace rules.
message TracingBackend {
  // Name of the backend, can be then used in Mesh.tracing.defaultBackend or in
  // TrafficTrace
  string name = 1 [ (doc.required) = true ];

  // Percentage of traces that will be sent to the backend (range 0.0 - 100.0).
  // Empty value defaults to 100.0%
  google.protobuf.DoubleValue sampling = 2;

  // Type of the backend (Kuma ships with 'zipkin')
  string type = 3 [ (doc.required) = true ];

  // Configuration of the backend
  google.protobuf.Struct conf = 4 [ (doc.required) = true ];
}

message DatadogTracingBackendConfig {
  // Address of datadog collector.
  string address = 1 [ (doc.required) = true ];

  // Port of datadog collector
  uint32 port = 2 [ (doc.required) = true ];

  // Determines if datadog service name should be split based on traffic
  // direction and destination. For example, with `splitService: true` and a
  // `backend` service that communicates with a couple of databases, you would
  // get service names like `backend_INBOUND`, `backend_OUTBOUND_db1`, and
  // `backend_OUTBOUND_db2` in Datadog. Default: false
  bool splitService = 3;
}

message ZipkinTracingBackendConfig {
  // Address of Zipkin collector.
  string url = 1 [ (doc.required) = true ];

  // Generate 128bit traces. Default: false
  bool traceId128bit = 2;

  // Version of the API. values: httpJson, httpJsonV1, httpProto. Default:
  // httpJson see
  // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/trace/v3/trace.proto#envoy-v3-api-enum-config-trace-v3-zipkinconfig-collectorendpointversion
  string apiVersion = 3 [ (doc.required) = true ];

  // Determines whether client and server spans will share the same span
  // context. Default: true.
  // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/trace/v3/zipkin.proto#config-trace-v3-zipkinconfig
  google.protobuf.BoolValue sharedSpanContext = 4;
}

message Logging {

  // Name of the default backend
  string defaultBackend = 1 [ (doc.required) = true ];

  // List of available logging backends
  repeated LoggingBackend backends = 2 [ (doc.required) = true ];
}

// LoggingBackend defines logging backend available to mesh. Backends can be
// used in TrafficLog rules.
message LoggingBackend {
  // Name of the backend, can be then used in Mesh.logging.defaultBackend or in
  // TrafficLogging
  string name = 1 [ (doc.required) = true ];

  // Format of access logs. Placeholders available on
  // https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log
  string format = 2;

  // Type of the backend (Kuma ships with 'tcp' and 'file')
  string type = 3 [ (doc.required) = true ];

  // Configuration of the backend
  google.protobuf.Struct conf = 4 [ (doc.required) = true ];
}

// FileLoggingBackendConfig defines configuration for file based access logs
message FileLoggingBackendConfig {
  // Path to a file that logs will be written to
  string path = 1 [ (doc.required) = true ];
}

// TcpLoggingBackendConfig defines configuration for TCP based access logs
message TcpLoggingBackendConfig {
  // Address to TCP service that will receive logs
  string address = 1 [ (doc.required) = true ];
}

// Routing defines configuration for the routing in the mesh
message Routing {
  // Enable the Locality Aware Load Balancing
  bool localityAwareLoadBalancing = 1;

  // Enable routing traffic to services in other zone or external services
  // through ZoneEgress. Default: false
  bool zoneEgress = 2;
}
